package com.ztsoft.user.config.jwt;

import com.alibaba.fastjson.JSON;
import com.ztsoft.user.pojo.constant.UserConstant;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定义JwtFilter 拦截器
 * 从请求的header中取出的token信息
 */
public class JwtFilter extends AccessControlFilter {
    private static final Logger logger = LoggerFactory.getLogger(JwtFilter.class);

    /**
     * 1. 返回true，shiro就直接允许访问url
     * 2. 返回false，shiro才会根据onAccessDenied的方法的返回值决定是否允许访问url
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        logger.info("访问拦截，进入认证！");
        //这里先让它始终返回false来使用onAccessDenied()方法
        return false;
    }

    /**
     * 如果返回true表示登录通过
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        logger.info("开始认证。。。");
//        //所以以后发起请求的时候就需要在Header中放一个Authorization，值就是对应的Token
//        HttpServletRequest req = (HttpServletRequest) request;
//        // 解决跨域问题
//        if (HttpMethod.OPTIONS.toString().matches(req.getMethod())) {
//            return true;
//        }
//        if (isLoginAttempt(request)) {
//            //获得JWtToken
//            JwtToken token = new JwtToken(req.getHeader(UserConstant.ACCESS_TOKEN));
//            try {
//                //委托给Realm进行验证
//                getSubject(request, response).login(token);
//                return true;
//            } catch (Exception e) {
//                logger.error("验证token出现异常", e);
//            }
//        }
//        //认证失败
//        onLoginFail(response);
//        return false;

        return true;
    }

    /**
     * 判断用户是否已经登录
     * 检测 header 里面是否包含 token 字段
     */
    protected boolean isLoginAttempt(ServletRequest request) {
        HttpServletRequest req = (HttpServletRequest) request;
        String authorization = req.getHeader(UserConstant.ACCESS_TOKEN);
        return authorization != null;
    }

    //登录失败时默认返回 401 状态码
    private void onLoginFail(ServletResponse response) throws IOException {
        Map<String, Object> resultMap = new HashMap<>();

        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        httpResponse.setContentType("application/json;charset=utf-8");

        resultMap.put("msg", "登录失败");
        resultMap.put("code", HttpServletResponse.SC_UNAUTHORIZED);

        httpResponse.getWriter().write(JSON.toJSONString(resultMap));
    }
}